{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# 车道提取"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "c4b29d9625332825"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "outputs": [],
   "source": [
    "import cv2\n",
    "import numpy as np\n",
    "\n",
    "# 提取出车道图像\n",
    "img = cv2.imread(\"./img/up01.png\")\n",
    "\n",
    "# 将图像按照HLS方式进行提取，希望在高亮度部分将车道线提取出来。\n",
    "hls = cv2.cvtColor(img,cv2.COLOR_BGR2HLS)\n",
    "\n",
    "# 将HLS三层进行分割\n",
    "channel_h = hls[:,:,0] # 颜色 0 - 120 红 120 - 240 绿 240 - 360 蓝色\n",
    "channel_l = hls[:,:,1] #\n",
    "channel_s = hls[:,:,2]\n",
    "\n",
    "# HLS 三层效果\n",
    "# cv2.imshow(\"h\",channel_h)\n",
    "# cv2.imshow(\"l\",channel_l)\n",
    "# cv2.imshow(\"s\",channel_s)\n",
    "# cv2.waitKey(0)\n",
    "\n",
    "# 利用sobel计算x方向的梯度\n",
    "# 通过Sobel边缘算子进行横向边缘检测。\n",
    "# 原因，因为车道本身是纵向的，如果用纵向检测，那就会失去掉这些边缘信息。\n",
    "# sobel_x 所有检测出来的边缘信息\n",
    "sobel_x = cv2.Sobel(channel_l,-1,1,0)\n",
    "# 防止负数的边缘信息出现\n",
    "abs_sobel_x = np.absolute(sobel_x)\n",
    "\n",
    "# print(abs_sobel_x.shape)\n",
    "# cv2.imshow(\"sobel\",abs_sobel_x)\n",
    "# cv2.waitKey(0)\n",
    "\n",
    "# 由于Sobel算子将一些重要的高亮度区域忽略掉，手动将低亮度区域调高。（127 -> 255）\n",
    "# Sobel中某些算子的大小超出了255，对原本图像进行压制（确保每个像素都在0-255）\n",
    "scaled_sobel = np.uint8(abs_sobel_x / np.max(abs_sobel_x) * 255)\n",
    "\n",
    "# cv2.imshow(\"sobel\",scaled_sobel)\n",
    "# cv2.waitKey(0)\n",
    "\n",
    "# 将高亮区域提取出来\n",
    "sx_binary = np.zeros_like(scaled_sobel)\n",
    "# 将图像中的高亮像素（> 170 且 <= 255）提取出来\n",
    "h,w = scaled_sobel.shape\n",
    "for i in range(h):\n",
    "    for j in range(w):\n",
    "        if 170 < scaled_sobel[i][j] <= 255:\n",
    "            sx_binary[i][j] = 255\n",
    "\n",
    "# cv2.imshow(\"sx_binary\",sx_binary)\n",
    "# cv2.waitKey(0)\n",
    "\n",
    "# 将饱和度较高的区域提取出来\n",
    "s_binary = np.zeros_like(channel_s)\n",
    "# 将图像中饱和度较高（> 100 且 <= 255）的部分提取出来\n",
    "h,w = channel_s.shape\n",
    "for i in range(h):\n",
    "    for j in range(w):\n",
    "        if 100 < channel_s[i][j] <= 255:\n",
    "            s_binary[i][j] = 255\n",
    "\n",
    "# cv2.imshow(\"s_binary\",s_binary)\n",
    "# cv2.waitKey(0)\n",
    "\n",
    "# 将高亮区域与饱和度较高的区域进行融合\n",
    "color_binary = (sx_binary | s_binary)\n",
    "cv2.imshow(\"color_binary\",color_binary)\n",
    "cv2.waitKey(0)"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "881fb05d445612e6"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
